

<template>
  <div class="flex flex-wrap gap-4 items-center" style="display: flex;  width: 100%; height: auto">
    <el-input class="searchInput" v-model="Id" style="width: 100px"  placeholder="ID"  />
    <el-input class="searchInput" v-model="UserName" style="width: 150px"  placeholder="姓名"  />
    <el-input class="searchInput" v-model="Phone" style="width: 130px"  placeholder="电话" />
    <el-input class="searchInput" v-model="Age" style="width: 70px"  placeholder="年龄" />
    <el-select-v2
        v-model="sexValue"
        :options="sexOptions"
        placeholder="性别"
        style="width: 100px; margin-top: 10px ;margin-right: 10px"
        clearable
    >
      <template #label="{ label }">
        <span>{{ label }} </span>

      </template>
    </el-select-v2>

    <el-select-v2
        v-model="roleValue"
        :options="roleOptions"
        placeholder="角色"
        style="width: 200px; margin-top: 10px;margin-right: 10px"
        clearable
        multiple
    >
      <template #label="{ label }">
        <span>{{ label }}</span>

      </template>
    </el-select-v2>
    <el-select-v2
        v-model="statusValue"
        :options="statusOptions"
        placeholder="状态"
        style="width: 100px; margin-top: 10px ;margin-right: 10px"
        clearable
    >
      <template #label="{ label }">
        <span>{{ label }} </span>

      </template>
    </el-select-v2>
    <el-button type="primary" @click="handleSearch" style="margin-left: 30px; margin-top: 10px ; margin-bottom: 10px ">
      <el-icon><Search /></el-icon>
    </el-button>
    <el-button type="primary" plain @click="showAddUserWindow" style="margin-left: 30px; margin-top: 10px ; margin-bottom: 10px ">
      <el-icon><plus /></el-icon>
    </el-button>
    <el-dialog
        v-model="dialogOverflowVisible"
        title="输入相关信息"
        width="500"
        draggable
        overflow
    >

      <el-form
          ref="ruleFormRef"
          style="max-width: 600px"
          :model="ruleForm"
          status-icon
          :rules="rules"
          label-width="auto"
          class="demo-ruleForm"
      >
        <!-- 用户名 -->
        <el-form-item label="用户名" prop="username" >
          <el-input v-model="ruleForm.username" :disabled="!isNameEditing" placeholder="请输入用户名" />
        </el-form-item>

        <!-- 密码 -->
        <el-form-item label="密码" prop="password">
          <el-input
              v-model="ruleForm.password"
              type="password"
              placeholder="请输入密码"
          />
        </el-form-item>

        <!-- 确认密码 -->
        <el-form-item label="确认密码" prop="checkPassword">
          <el-input
              v-model="ruleForm.checkPassword"
              type="password"
              placeholder="请再次输入密码"
          />
        </el-form-item>

        <!-- 手机号 -->
        <el-form-item label="手机号" prop="phone">
          <el-input v-model="ruleForm.phone" placeholder="请输入电话号码" />
        </el-form-item>

        <!-- 年龄 -->
        <el-form-item label="年龄" prop="age">
          <el-input
              v-model.number="ruleForm.age"
              type="number"
              placeholder="请输入年龄"
          />
        </el-form-item>

        <!-- 性别 -->
        <el-form-item label="性别" prop="sex">
          <el-radio-group v-model="ruleForm.sex">
            <el-radio label="男">男</el-radio>
            <el-radio label="女">女</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 角色 -->
        <el-form-item label="角色" prop="rankId">
          <el-select v-model="ruleForm.rankId" placeholder="请选择角色">
            <el-option label="超级管理员" value="0" />
            <el-option label="普通管理员" value="1" />
            <el-option label="员工" value="2" />
          </el-select>
        </el-form-item>





        <div class="dialog-footer" style="margin-left: 300px">

          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
            <el-button v-if="isNameEditing"  type="primary" @click="submitForm(ruleFormRef)">
              确认添加
            </el-button>
          <el-button v-if="!isNameEditing" type="primary" @click="editUserInformation">
            确认修改
          </el-button>

        </div>
      </el-form>
    </el-dialog>
  </div>
  <el-main>
    <el-scrollbar >
      <el-table :data="tableData"  style="height: 450px; width: 100%" >
        <el-table-column prop="id" label="ID" width="100" >
        <template  #default="scope">
          <el-tag type="primary">{{ scope.row.id }}</el-tag>
        </template>
        </el-table-column>
        <el-table-column prop="username" label="用户名" width="120" >
          <template  #default="scope">
            <el-tag type="primary">{{ scope.row.username }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="sex" label="性别" width="100" >
          <template #default="scope">
          <template v-if="scope.row.sex === '0'"><el-tag type="primary">男</el-tag></template>
          <template v-else-if="scope.row.sex === '1'"><el-tag type="success">女</el-tag></template>
          </template>
        </el-table-column>
        <el-table-column prop="age" label="年龄" width="120" >
          <template #default="scope">
            <el-tag type="primary">{{ scope.row.age }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="phone" label="电话" width="150" >
          <template #default="scope">
            <el-tag type="primary">{{ scope.row.phone }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="rankId" label="角色" width="180" >
          <template #default="scope">
            <template v-if="scope.row.rankId === '0'"><el-tag type="primary">超级管理员</el-tag></template>
            <template v-else-if="scope.row.rankId === '1'"><el-tag type="success">普通管理员</el-tag></template>
            <template v-else-if="scope.row.rankId === '2'"><el-tag type="success">员工</el-tag></template>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="150px"  >



          <template #default="scope">
            <template v-if="scope.row.status === '0'" ><el-tag type="primary" @click="changeStatus(scope.row)">启用中</el-tag></template>
            <template v-else-if="scope.row.status === '1'" ><el-tag type="warning" @click="changeStatus(scope.row)">禁用中</el-tag></template>
          </template>

        </el-table-column>
        <el-table-column label="操作" width="180">
          <template #default="scope">
                <el-button type="primary" size="small" @click="edit(scope.row)">编辑</el-button>



            <el-popconfirm @confirm=deleteUser(scope.row)
                class="box-item"
                title="确认删除吗？"
                placement="bottom-end"
            >
              <template #reference>
                <el-button type="danger" size="small">删除</el-button>
              </template>
            </el-popconfirm>

          </template>
        </el-table-column>
      </el-table>
    </el-scrollbar>
  </el-main>



  <div class="demo-pagination-block">
    <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[20, 50, 100, 200]"
        :size="size"
        :disabled="disabled"
        :background="background"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        :teleported="teleported"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
    />
  </div>


</template>
<script setup lang="ts">

import {ref, reactive,nextTick} from "vue";
import axios from "axios";
import {ComponentSize, ElMessage, ElMessageBox, FormInstance, FormRules} from 'element-plus'
import {Plus, Search} from "@element-plus/icons-vue";




const currentPage = ref(1)
const pageSize = ref(20)
const size = ref<ComponentSize>('default')
const background = ref(true)
const disabled = ref(false)
const teleported = ref(true)
let total=ref(0)
let tableData = ref([])
let Id = ref('')
let UserName = ref('')
let Age = ref('')
let Phone = ref('')
let isNameEditing = ref(true)

const sexValue = ref('')
const roleValue = ref<string[]>([])
const statusValue = ref('')
const sexOptions = [
  { value: "0", label: "男" },
  { value: "1", label: "女" }
];
const roleOptions = [
  {
    value: '0',
    label: '超级管理员'
  },
  {
    value: '1',
    label: '普通管理员'
  },
  {
    value: '2',
    label: '员工'
  }
]
const statusOptions = [
  {
    value: '0',
    label: '启用中'
  },
  {
    value: '1',
    label: '禁用中'
  }
]
axios.get('http://localhost:8080/user/findUserByCondition', {
  params: {
    pageNum: currentPage.value,
    pageSize: pageSize.value,
  },
  paramsSerializer: function (params) {
    // 自定义参数序列化
    return new URLSearchParams(params).toString();
  }
}).then((res) => {
  tableData.value = res.data.data; // 确保后端返回的数据结构正确
  total.value = res.data.total;
}).catch((error) => {
  console.error("请求失败:", error);
});

function changePage(){
  axios.get('http://localhost:8080/user/findUserByCondition', {
    params: {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
    },
    paramsSerializer: function (params) {
      // 自定义参数序列化
      return new URLSearchParams(params).toString();
    }
  }).then((res) => {
    tableData.value = res.data.data; // 确保后端返回的数据结构正确
    total.value = res.data.total;
  }).catch((error) => {
    console.error("请求失败:", error);
  });
}



const handleSizeChange = (val: number) => {
  console.log(`${val} items per page`)
  changePage()
}
const handleCurrentChange = (val: number) => {
  console.log(`current page: ${val}`)
  changePage()
}

function handleSearch(){
  const res = axios.get('http://localhost:8080/user/findUserByCondition', {
    params: {
      pageNum:currentPage.value,
      pageSize: pageSize.value,
      id: Id.value === undefined ? '' : Id.value,
      username: UserName.value === undefined ? '' : UserName.value,
      sex: sexValue.value === undefined ? '' : sexValue.value,
      age: Age.value === undefined ? '' : Age.value,
      phone: Phone.value === undefined ? '' : Phone.value,
      rankId: roleValue.value === undefined ? '' : roleValue.value,
      status: statusValue.value === undefined ? '' : statusValue.value,
    },
    paramsSerializer: function (params) {
      // 自定义参数序列化
      return new URLSearchParams(params).toString();
    }
  }).then((res) => {
    tableData.value = res.data.data; // 确保后端返回的数据结构正确
    total.value = res.data.total;
  }).catch((error) => {
    console.error("请求失败:", error);
  });
}


const dialogOverflowVisible = ref(false)
const ruleFormRef = ref<FormInstance>()

const validateUsername = (rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error('请输入用户名'));
  } else if (value.length < 3 || value.length > 15) {
    callback(new Error('用户名长度必须在3到15位之间'));
  } else {
    callback();
  }
};

const validatePassword = (rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error('请输入密码'));
  } else if (value.length < 6 || value.length > 15) {
    callback(new Error('密码长度必须在6到15位之间'));
  } else {
    // 确保ruleFormRef存在后触发确认密码校验
    nextTick(() => {
      if (ruleFormRef.value) {
        ruleFormRef.value.validateField('checkPassword');
      }
    });
    callback();
  }
};


const validatePassword2 = (rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error('请再次输入密码'));
  } else if (value !== ruleForm.password) {
    callback(new Error('两次输入密码不一致'));
  } else {
    callback();
  }
};

const validatePhone = (rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error('请输入电话号码'));
  } else {
    const phoneRegex = /^1[0-9]{10}$/;
    if (!phoneRegex.test(value)) {
      callback(new Error('电话号码必须是11位数字且以1开头'));
    } else {
      callback();
    }
  }
};

const checkAge = (rule: any, value: any, callback: any) => {
  if (value === '' || value === null || value === undefined) {
    return callback(new Error('请输入年龄'));
  }

  const numValue = Number(value);
  if (isNaN(numValue)) {
    callback(new Error('请输入有效数字'));
  } else if (!Number.isInteger(numValue)) {
    callback(new Error('年龄必须是整数'));
  } else if (numValue < 18 || numValue > 65) {
    callback(new Error('年龄必须在18到65之间'));
  } else {
    callback();
  }
};

const validateSex = (rule: any, value: any, callback: any) => {
  if (value === '' || value === null || value === undefined) {
    callback(new Error('请选择性别'));
  } else {
    callback();
  }
};

const validateRole = (rule: any, value: any, callback: any) => {
  if (value === '' || value === null || value === undefined) {
    callback(new Error('请选择角色'));
  } else {
    callback();
  }
};

let ruleForm = reactive({
  id: '',
  username: '',
  password: '',
  checkPassword: '',
  age: '',
  phone: '',
  sex: '',
  rankId: '',
});

const rules = reactive<FormRules<typeof ruleForm>>({
  username: [
    { required: true, validator: validateUsername, trigger: 'blur' },
    { required: true, validator: validateUsername, trigger: 'input' },
    { required: true, validator: validateUsername, trigger: 'change' }
  ],
  password: [
    { required: true, validator: validatePassword, trigger: 'blur' },
    { required: true, validator: validatePassword, trigger: 'input' }
  ],
  checkPassword: [
      { required: true, validator: validatePassword2, trigger: 'blur' },
    { required: true, validator: validatePassword2, trigger: 'input' }
  ],
  age: [
    { required: true, validator: checkAge, trigger: 'input' }
  ],
  phone: [
    { required: true, validator: validatePhone, trigger: 'input' }
  ],
  sex: [
    { required: true, validator: validateSex, trigger: 'change' }
  ],
  rankId: [
    { required: true, validator: validateRole, trigger: 'change' }
  ],
});

const submitForm = (formEl: FormInstance | undefined) => {
  isNameEditing.value = true
  if (!formEl) return;

  formEl.validate((valid) => {
    if (valid) {
      add(); // 仅在验证通过时调用add
      console.log('submit!');
      dialogOverflowVisible.value = false
    } else {
      console.log('error submit!');
      // 不需要返回 false，只需处理错误情况
    }
  });
};

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  ruleForm.username = ''
  ruleForm.sex  = ''
  ruleForm.rankId = ''
  ruleForm.age = ''
  ruleForm.phone = ''
  ruleForm.password = ''
  ruleForm.checkPassword = ''
  formEl.resetFields()
}



function add() {

  console.log("添加用户");
  axios.post('http://localhost:8080/user/addUser', {
    username: ruleForm.username+'',
    password: ruleForm.password+'',
    age: ruleForm.age,
    phone: ruleForm.phone+'',
    sex: ruleForm.sex==='男'? '0' : '1',
    rankId: ruleForm.rankId+''
  }).then((res) => {
    let msg = res.data.msg;
    if (res.data.code === 0) {
      console.log(msg);
      ruleForm.username = ''
      ruleForm.sex  = ''
      ruleForm.rankId = ''
      ruleForm.age = ''
      ruleForm.phone = ''
      ruleForm.password = ''
      ruleForm.checkPassword = ''
      resetForm(ruleFormRef.value);
      dialogOverflowVisible.value = false;
      alert(msg)
      changePage();
    } else if (res.data.code === 1) {
      alert(msg)
    }
  }).catch((error) => {
    console.error("请求失败:", error);
    ElMessage({
      message: '请求失败，请稍后再试',
      type: 'error',
    });
  });
}

function showAddUserWindow(){
  isNameEditing.value = true
  dialogOverflowVisible.value = true;
  ruleForm.username = ''
  ruleForm.sex  = ''
  ruleForm.rankId = ''
  ruleForm.age = ''
  ruleForm.phone = ''
  ruleForm.password = ''
  ruleForm.checkPassword = ''
}

//编辑与删除
function edit(row:any) {
  isNameEditing.value = false; // 设置为编辑模式
  dialogOverflowVisible.value = true; // 显示对话框

  console.log('row:', row);
  console.log('ruleForm:', ruleForm);
  ruleForm.id = row.id + '';
  ruleForm.username = row.username + '';

  // 性别数据映射：后端返回的是 '0' 或 '1'，前端控件选项是 '男' 或 '女'
  ruleForm.sex = row.sex === '0' ? '男' : '女';

  // 角色数据映射：后端返回的是 '0'、'1' 或 '2'，前端控件选项是 '1'、'2' 或 '3'
  const roleMap = { '0': '1', '1': '2', '2': '3' };
  ruleForm.rankId = row.rankId || '3'; // 默认为员工

  ruleForm.age = row.age;
  ruleForm.phone = row.phone;
  ruleForm.password = ''; // 清空密码字段
  ruleForm.checkPassword = '';



  // 重置表单验证状态
  nextTick(() => {
    if (ruleFormRef.value) {
      ruleFormRef.value.clearValidate();
    }
  });
}
function editUserInformation() {
  // 表单验证
  if (!ruleFormRef.value) return;

  ruleFormRef.value.validate((valid) => {
    if (valid) {
      // 调用后端接口更新用户信息
      axios.put('http://localhost:8080/user/updateUserById', {
        // 确保用户ID正确传递
        id: ruleForm.id+'',
        username: ruleForm.username+'',
        password: ruleForm.password+'',
        age: ruleForm.age,
        phone: ruleForm.phone+'',
        sex: ruleForm.sex==='男' ? '0' : '1',
        rankId: ruleForm.rankId+''
      }).then((res) => {
        let msg = res.data.msg;
        if (res.data.code === 0) {
          ElMessage.success(msg);
          dialogOverflowVisible.value = false; // 关闭对话框
          resetForm(ruleFormRef.value); // 重置表单
          changePage(); // 刷新用户列表
        } else {
          ElMessage.error(msg);
        }
      }).catch((error) => {
        console.error("请求失败:", error);
        ElMessage.error('更新失败，请稍后再试');
      });
    } else {
      console.log('验证失败');
    }
  });
}
function deleteUser(row){
  axios.delete('http://localhost:8080/user/deleteUserById',
      {
        params: {
          id: row.id
        }
      }
  ).then((res) => {
    let msg = res.data.msg;
    if (res.data.code === 0) {
      console.log(msg);
      ElMessage.success(msg)
      alert(msg)
      changePage();
    } else if (res.data.code === 1) {
      ElMessage.error(msg)
    }
  }).catch((error) => {
    console.error("请求失败:", error);
    ElMessage({
      message: '请求失败，请稍后再试',
      type: 'error',
    });
  });
}
function changeStatus(row){
  axios.put('http://localhost:8080/user/changeStatus', {
    id: row.id,
    status: row.status==='1' ? '0' : '1'
  }).then((res) => {
    let msg = res.data.msg;
    if (res.data.code === 0) {
      console.log(msg);
      ElMessage.success(msg)
      changePage();
    } else if (res.data.code === 1) {
      ElMessage.error(msg)
    }
  }).catch((error) => {})

}


</script>

<style scoped>
.demo-pagination-block {
  margin-top: 10px;
}
.demo-pagination-block  {
  margin-bottom: 16px;
}
.searchInput {
  margin-right: 10px;
  height: 30px;
  margin-top: 10px;
}</style>